use std::{
    net::SocketAddr,
    path::PathBuf,
};
use tokio::{
    fs::File,
    io::{AsyncReadExt, AsyncWriteExt, BufReader, BufWriter},
    net::{TcpListener, TcpStream},
    sync::mpsc,
};
use crate::core::DeviceInfo;
use log::{info, error};
use crate::core::{Command,TransferCommand};

// 服务结构
pub struct TransferService {
    pub handle: tokio::task::JoinHandle<()>,
}
// 启动文件传输服务
pub async fn start_transfer_service(port: u16,cmd_tx: mpsc::Sender<Command>) -> Result<TransferService, Box<dyn std::error::Error + Send + Sync>> {
    let listener = TcpListener::bind(format!("0.0.0.0:{}", port)).await?;
    let handle = tokio::spawn(async move {
        loop {
            match listener.accept().await {
                Ok((stream, addr)) => {
                    tokio::spawn(handle_transfer_connection(stream, addr, cmd_tx.clone()));
                }
                Err(e) => error!("接受连接失败: {}", e),
            }
        }
    });

    Ok(TransferService { handle })
}

// 处理文件传输连接
pub async fn handle_transfer_connection(
    mut stream: TcpStream,
    addr: SocketAddr,
    cmd_tx: mpsc::Sender<Command>,
) {
    info!("新的传输连接: {}", addr);
    let mut buffer = [0; 1024];
    match stream.read(&mut buffer).await {
        Ok(0) => return, // 连接关闭
        Ok(len) => {
            if let Ok(cmd) = serde_json::from_slice::<TransferCommand>(&buffer[..len]) {
                match cmd {
                    TransferCommand::SendFile(filename, size) => {
                        receive_file(&mut stream, &filename, size).await;
                    }
                    TransferCommand::RequestFile(filename) => {
                        send_requested_file(&mut stream, &filename).await;
                    }
                }
            }
        }
        Err(e) => error!("读取错误: {}", e),
    }
}

// 接收文件
pub async fn receive_file(stream: &mut TcpStream, filename: &str, size: u64) {
    let path = PathBuf::from(filename);
    match File::create(&path).await {
        Ok(file) => {
            let mut writer = BufWriter::new(file);
            let mut received = 0;
            let mut buffer = vec![0; 8192];

            while received < size {
                let to_read = (size - received).min(buffer.len() as u64) as usize;
                match stream.read_exact(&mut buffer[..to_read]).await {
                    Ok(_) => {
                        if let Err(e) = writer.write_all(&buffer[..to_read]).await {
                            error!("写入文件错误: {}", e);
                            break;
                        }
                        received += to_read as u64;
                        print!(
                            "\r接收 {}: {:.1}%",
                            filename,
                            (received as f64 / size as f64) * 100.0
                        );
                    }
                    Err(e) => {
                        error!("\n读取错误: {}", e);
                        break;
                    }
                }
            }

            writer.flush().await.unwrap();
            info!("\n文件接收完成: {}", filename);
        }
        Err(e) => error!("创建文件失败: {}", e),
    }
}

// 发送被请求的文件
pub async fn send_requested_file(stream: &mut TcpStream, filename: &str) {
    match File::open(filename).await {
        Ok(file) => {
            let metadata = file.metadata().await.unwrap();
            let file_size = metadata.len();
            
            // 发送文件信息
            let cmd = TransferCommand::SendFile(filename.to_string(), file_size);
            let data = serde_json::to_vec(&cmd).unwrap();
            if let Err(e) = stream.write_all(&data).await {
                error!("发送文件信息失败: {}", e);
                return;
            }

            // 发送文件内容
            let mut reader = BufReader::new(file);
            let mut sent = 0;
            let mut buffer = vec![0; 8192];

            while sent < file_size {
                let to_send = (file_size - sent).min(buffer.len() as u64) as usize;
                match reader.read_exact(&mut buffer[..to_send]).await {
                    Ok(_) => {
                        if let Err(e) = stream.write_all(&buffer[..to_send]).await {
                            error!("发送文件错误: {}", e);
                            break;
                        }
                        sent += to_send as u64;
                        print!(
                            "\r发送 {}: {:.1}%",
                            filename,
                            (sent as f64 / file_size as f64) * 100.0
                        );
                    }
                    Err(e) => {
                        error!("\n读取文件错误: {}", e);
                        break;
                    }
                }
            }

            stream.flush().await.unwrap();
            info!("\n文件发送完成: {}", filename);
        }
        Err(e) => error!("打开文件失败: {}", e),
    }
}

// 发送文件到指定设备
pub async fn send_file(device: &DeviceInfo, file_path: &str) -> Result<(), Box<dyn std::error::Error>> {
    let addr = SocketAddr::new(device.ip, device.transfer_port);
    let mut stream = TcpStream::connect(addr).await?;
    // 发送文件请求
    let cmd = TransferCommand::RequestFile(file_path.to_string());
    let data = serde_json::to_vec(&cmd)?;
    stream.write_all(&data).await?;
    // 等待并接收文件
    let mut buffer = [0; 1024];
    let len = stream.read(&mut buffer).await?;
    let response_cmd = serde_json::from_slice::<TransferCommand>(&buffer[..len])?;
    if let TransferCommand::SendFile(filename, size) = response_cmd {
        info!("开始接收文件: {} ({} 字节)", filename, size);
        receive_file(&mut stream, &filename, size).await;
    } else {
        return Err("未收到文件发送命令".into());
    }
    Ok(())
}

